package com.nero.controller;

import com.nero.bean.BaseMessage;
import com.nero.bean.PO.TbAdmin;
import com.nero.common.pojo.TaotaoResult;
import com.nero.security.ShiroDbRealm;
import com.nero.service.IAdminService;
import com.nero.service.IUserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Nero on 18/8/6.
 */
@Controller
@RequestMapping("/login")
public class LoginController {
    @Resource
    IUserService userServiceImpl;
    @Resource
    IAdminService adminServiceImpl;
    @Resource
    ShiroDbRealm shiroDbRealm;

    Logger logger = LogManager.getLogger(this.getClass());


    //    @RequestMapping("/verify")
    @ResponseBody
    public BaseMessage verify(@RequestBody TbAdmin tbAdmin,
                              HttpServletRequest request, HttpServletResponse response) {
        BaseMessage baseMessage = new BaseMessage();
        TbAdmin in = adminServiceImpl.login(tbAdmin);
        if (in != null) {
            request.getSession().setAttribute("tbAdmin", tbAdmin);
            baseMessage.setSuccess(1);
        } else baseMessage.setSuccess(0);
        return baseMessage;
    }

    @RequestMapping("/verify")
    @ResponseBody
    public TaotaoResult shiroVerify(@RequestBody TbAdmin user, Model model) {
//        shiroDbRealm.setUserServiceImpl(userServiceImpl);
        logger.info("username: " + user.getUsername());
        logger.info("password: " + user.getPassword());
        //生成用户名和密码token
        UsernamePasswordToken token =
                new UsernamePasswordToken(user.getUsername(), user.getPassword());
        //获取当前用户Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            //传递token给shiro,调用doGetAuthenticationInfo这个方法(即:登录验证)
            currentUser.login(token);
//            System.out.println("HHHHHHHHH");

        } catch (AuthenticationException e) {//登录失败
            e.printStackTrace();
            return TaotaoResult.build(200, "unauthorized");
        }
        model.addAttribute("roles", getRoleList());
        System.out.println("ROLES:" + getRoleList().get(0));
        return TaotaoResult.ok();
    }

    List<String> getRoleList() {
        List<String> list = new ArrayList<>();
        Subject currentUser = SecurityUtils.getSubject();
        System.out.println(currentUser.isPermitted("admin:del"));
        System.out.println(currentUser.isPermitted("admin:ADD"));
        if (currentUser.hasRole("oper")) {
            list.add("oper");
        }
        return list;
    }


    @RequiresPermissions("oper:add")//执行需要”oper:add”权限
    @RequestMapping("/add.do")
    public String add(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //userService.add();
        System.out.println("addaddadd");
        return "a";
    }

    @RequiresPermissions("oper:delBtn")//执行需要”oper:del”权限
    @RequestMapping("/del.do")
    public void del(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("bbbbb");
    }

    @RequiresRoles("admin")
    @RequestMapping("/query.do")
    public void query(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("CCCCC");

    }

    @RequestMapping("/logout.do")
    public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            try {
                subject.logout();
            } catch (Exception ex) {
            }
        }
        response.sendRedirect("/index.jsp");
    }

    private String loginUser(TbAdmin user) {
        if (isRelogin(user)) return "SUCC"; // 如果已经登陆，无需重新登录

        return shiroLogin(user); // 调用shiro的登陆验证
    }

    private String shiroLogin(TbAdmin user) {
        // 组装token，包括客户公司名称、简称、客户编号、用户名称；密码
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword().toCharArray(), null);
        token.setRememberMe(true);

        // shiro登陆验证
        try {
            SecurityUtils.getSubject().login(token);
        } catch (UnknownAccountException ex) {
            return "用户不存在或者密码错误！";
        } catch (IncorrectCredentialsException ex) {
            return "用户不存在或者密码错误！";
        } catch (AuthenticationException ex) {
            return ex.getMessage(); // 自定义报错信息
        } catch (Exception ex) {
            ex.printStackTrace();
            return "内部错误，请重试！";
        }
        return "SUCC";
    }

    private boolean isRelogin(TbAdmin user) {
        Subject us = SecurityUtils.getSubject();
        if (us.isAuthenticated()) {
            return true; // 参数未改变，无需重新登录，默认为已经登录成功
        }
        return false; // 需要重新登陆
    }
}
